package org.mii.safeguard.v1.security.web;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.mii.safeguard.v1.ServiceException;
import org.mii.safeguard.v1.security.entity.Authority;
import org.mii.safeguard.v1.security.entity.Role;
import org.mii.safeguard.v1.security.service.AuthorityManager;
import org.mii.safeguard.v1.security.service.AuthorityUtils;
import org.mii.safeguard.v1.security.service.RoleManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springside.modules.orm.hibernate.HibernateWebUtils;
import org.springside.modules.utils.AjaxJQueryUtils;
import org.springside.modules.web.struts2.CRUDActionSupport;
import org.springside.modules.web.struts2.Struts2Utils;

/**
 * 角色管理Action.
 * 
 * 使用Struts2 convention-plugin annotation定义Action参数.
 * 
 * @author calvin
 */
@SuppressWarnings("serial")
@Results( { @Result(name = CRUDActionSupport.RELOAD, location = "role.action", type = "redirect") })
@Namespace("/security")
public class RoleAction extends CRUDActionSupport<Role> {

	@Autowired
	private RoleManager roleManager;
	@Autowired
	private AuthorityManager authorityManager;

	// 基本属性
	private Role entity;
	private Long id;
	private List<Role> allRoles;

	private Long roleId;

	// 权限相关属性
	private List<Authority> allAuths; // 全部可选权限列表
	private List<Long> checkedAuthIds;// 页面中钩选的权限id列表

	// 基本属性访问函数 //

	public Role getModel() {
		return entity;
	}

	@Override
	protected void prepareModel() throws Exception {
		if (id != null) {
			entity = roleManager.get(id);
		} else {
			entity = new Role();
		}
	}

	public void setId(Long id) {
		this.id = id;
	}

	public List<Role> getAllRoles() {
		return allRoles;
	}

	// CRUD Action 函数 //

	@Override
	public String list() throws Exception {
		allRoles = roleManager.getAll();
		return SUCCESS;
	}

	@Override
	public String input() throws Exception {
		allAuths = authorityManager.getAll();
		checkedAuthIds = entity.getAuthIds();
		return INPUT;
	}

	@Override
	public String save() throws Exception {
		// 根据页面上的checkbox 整合Role的Authorities Set.
		HibernateWebUtils.mergeByCheckedIds(entity.getAuthorities(),
				checkedAuthIds, Authority.class);
		// 白衣这个方法写得好啊，一下子就将权限更新过了
		roleManager.save(entity);
		addActionMessage("保存角色成功");
		return RELOAD;
	}

	@Override
	public String delete() throws Exception {
		try {
			roleManager.delete(id);
			addActionMessage("删除角色成功");
		} catch (ServiceException e) {
			logger.error(e.getMessage(), e);
			addActionMessage(e.getMessage());
		}
		return RELOAD;
	}

	public String authRole() throws Exception {
		// String roleId = request.getParameter("roleId");
		Role role = roleManager.get(Long.valueOf(id));
		setRoleId(id);
		allAuths = authorityManager.getAll();
		authorityManager.labelAuthorited(allAuths, role.getAuthIds());
		AuthorityUtils.identifierAuths(allAuths, role.getAuthIds(),
				Authority.class, "id");
		return "authority";
	}

	/**
	 * AJAX Asynchronous Method
	 * 
	 * @return null. because the page didn't change, so return null
	 * @throws Exception
	 */
	public String modifyRoleAuths() throws Exception {
		HttpServletRequest request = Struts2Utils.getRequest();
		JSONObject jsonObject = AjaxJQueryUtils.readJson(request);
		String authId = jsonObject.getString("aId");
		String roleId = jsonObject.getString("roleId");
		entity = roleManager.get(Long.valueOf(roleId));

		int udt = AuthorityUtils.updateAuthorites(entity.getAuthorities(), Long
				.valueOf(authId), Authority.class);

		// 重新保存
		roleManager.save(entity);
		AjaxJQueryUtils.print(Struts2Utils.getResponse(), String.valueOf(udt));
		return null;
	}

	// 其他属性访问函数及Action函数 //

	public List<Authority> getAllAuths() {
		return allAuths;
	}

	public List<Long> getCheckedAuthIds() {
		return checkedAuthIds;
	}

	public void setCheckedAuthIds(List<Long> checkedAuthIds) {
		this.checkedAuthIds = checkedAuthIds;
	}

	public Long getRoleId() {
		return roleId;
	}

	public void setRoleId(Long roleId) {
		this.roleId = roleId;
	}
}